﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Xml.Linq;
using PoznanEvents.Events;
using PoznanEvents.Models;


namespace PoznanEvents.ViewModels
{
    public class MainViewModel : INotifyPropertyChanged
    {

        public EventModel _eventModel;
        public event EventHandler<EventArgs> SetLoadingBar;
        public event EventHandler<EventArgs> CloseLoadingBar;
        private XDocument ResultXDocument;
        private IEnumerable<Event> AllEventData;
        private DateTime Now = DateTime.Now;
        public bool IsDataLoaded
        {
            get;
            private set;
        }


        public MainViewModel()
        {
            _eventModel = new EventModel();
            _eventModel.CurrentDayEventsCompleted += CurrentDayEventsCompleted;
            _eventModel.EventsRangeDateCompleted += EventsRangeDateCompleted;
            _eventModel.EventsFromDayCompleted += EventsFromDayCompleted;
        }



        #region view binding items
        
        private Event _selectedEvent;
        public Event SelectedEvent
        {
            get { return _selectedEvent; }
            set
            {
                if (value != null)
                {
                    _selectedEvent = value;
                    NotifyPropertyChanged("SelectedEvent");
                }
            }
            
        }

        private ObservableCollection<Event> todayEvents;
        public ObservableCollection<Event> TodayEvents
        { 
            get 
            { 
                return todayEvents; 
            }
            set
            {
                if (value != null)
                {
                    todayEvents = value;
                    NotifyPropertyChanged("TodayEvents");
                }
            } 
        }

        private ObservableCollection<Event> threeDaysEvenst;
        public ObservableCollection<Event> ThreeDaysEvents
        {
            get { return threeDaysEvenst; }
            set
            {
                if (value != null)
                {
                    threeDaysEvenst = value;
                    NotifyPropertyChanged("ThreeDaysEvents");
                }
            }
        }

        private ObservableCollection<Event> weekEvents;
        public ObservableCollection<Event> WeekEvents
        {
            get { return weekEvents; }
            set
            {
                if (value != null)
                {
                    weekEvents = value;
                    NotifyPropertyChanged("WeekEvents");
                    CloseLoadingBar(this, new EventArgs());
                    IsDataLoaded = true;
                }
            }
        }
        #endregion

        #region events
        public void EventsRangeDateCompleted(object sender, getEventsCompletedEventArgs args)
        {
            ResultXDocument = XDocument.Parse(args.Result.@return.ToString());
            SetEvents();
        }

        public void EventsFromDayCompleted(object sender, getEventsFromDateCompletedEventArgs args)
        {
            ResultXDocument = XDocument.Parse(args.Result.@return.ToString());
            SetEvents();
        }

        public void CurrentDayEventsCompleted(object sender, getCurrentDayEventsCompletedEventArgs args)
        {
            ResultXDocument = XDocument.Parse(args.Result.@return.ToString());
            SetEvents();
        }
        #endregion

        #region helper
        public void LoadData()
        {
            Now = DateTime.Now;
            var today = DateTime.Now;
            _eventModel.GetDataDateRange(today, today.AddDays(7));
        }

        public void LoadCurrentData()
        {
            ThreeDaysEvents = new ObservableCollection<Event>();
            WeekEvents = new ObservableCollection<Event>();
            var todayEvents = from Event _event in AllEventData
                              where _event.EventDateStart > Now && _event.EventDateStart < Now.AddDays(1)
                              select _event;

            TodayEvents = new ObservableCollection<Event>(todayEvents);
            CloseLoadingBar(this, new EventArgs());
        }

        public void LoadThreeDaysData()
        {
            TodayEvents = new ObservableCollection<Event>();
            WeekEvents = new ObservableCollection<Event>();

            var threeDayEvents = from Event _event in AllEventData
                                 where _event.EventDateStart > Now.AddDays(1) && _event.EventDateStart < Now.AddDays(3)
                                 select _event;

            ThreeDaysEvents = new ObservableCollection<Event>(threeDayEvents);
            CloseLoadingBar(this, new EventArgs());
        }

        public void LoadSevenDaysData()
        {
            TodayEvents = new ObservableCollection<Event>();
            ThreeDaysEvents = new ObservableCollection<Event>();

            var weekeEvents = from Event _event in AllEventData
                              where _event.EventDateStart > Now.AddDays(3) && _event.EventDateStart < Now.AddDays(7)
                              select _event;

            WeekEvents = new ObservableCollection<Event>(weekeEvents);
            CloseLoadingBar(this, new EventArgs());
        }


        public void LoadAllData()
        {
            var todayEvents = from Event _event in AllEventData
                              where _event.EventDateStart > Now && _event.EventDateStart < Now.AddDays(1)
                              select _event;

            TodayEvents = new ObservableCollection<Event>(todayEvents);

            var threeDayEvents = from Event _event in AllEventData
                                 where _event.EventDateStart > Now && _event.EventDateStart < Now.AddDays(3)
                                 select _event;

            ThreeDaysEvents = new ObservableCollection<Event>(todayEvents);

            var weekeEvents = from Event _event in AllEventData
                              where _event.EventDateStart > Now && _event.EventDateStart < Now.AddDays(7)
                              select _event;

            WeekEvents = new ObservableCollection<Event>(todayEvents);
        }

        public void ClearAllData()
        {
            TodayEvents = new ObservableCollection<Event>();
            WeekEvents = new ObservableCollection<Event>();
            ThreeDaysEvents = new ObservableCollection<Event>();
        }

        public void ReLoadData()
        {
            TodayEvents = new ObservableCollection<Event>();
            ThreeDaysEvents = new ObservableCollection<Event>();
            WeekEvents = new ObservableCollection<Event>();

            SetLoadingBar(this, new EventArgs());
            LoadData();
        }



        private void SetEvents()
        {
            AllEventData = from e in ResultXDocument.Descendants("event")
                             orderby e.Element("event_start").Value
                           select new Event(e.Element("event_id"), e.Element("event_author"), e.Element("event_address"), e.Element("event_start"),
                                 e.Element("event_end"), e.Element("event_url"), e.Element("event_version"), e.Element("event_keywords"));
            IsDataLoaded = true;
            LoadAllData();
        }

        #endregion

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}